home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / math / alged34.zip / ALGEDSRC.ZIP / ALGMAIN.C < prev    next >
C/C++ Source or Header  |  1996-06-06  |  13KB  |  373 lines

  1. /*--------------------------------------------------------------------
  2.    Alged:  Algebra Editor
  3.  
  4.    Copyright (c) 1994,1996 John Henckel
  5.    Permission to use, copy, modify, distribute and sell this software
  6.    and its documentation for any purpose is hereby granted without fee,
  7.    provided that the above copyright notice appear in all copies.
  8.  
  9.    Notes;
  10.    This was written using the excellent Borland Turbo C++ 3.0 Compiler.
  11.    One of the concepts that occurs regularly in this program is the clag.
  12.    A clag is a commutative-left-associative-group.  For instance,
  13.    x+y+z is a clag, but x-y-z is not, because SUB doesn't commute.
  14.    And x+(y+z) is not a clag because it is right associative.  Clags are
  15.    either additive or multiplicative.  You can sort, cancel, and combine
  16.    elements of a clag.  You can move numbers to the bottom (front) or
  17.    top (end) of a clag.  You can split and join clags by converting
  18.    MUL and ADD to/from DIV and SUB.  I think most people think in terms
  19.    of clags, though they don't call them that.
  20.  
  21.    Notes:  The following compiler flags are required:
  22.      word alignment off, memory large, signed chars, enums as int.
  23.    These are recommended:  floating point emulation, fast float, 8086 inst.
  24.  
  25.    If you make any enhancements to this code, please comment them well and
  26.    make a note below.  I would appreciate it if you send me your enhancements
  27.    also!  There are a number of utility function you should be aware of,
  28.    look at cons, newoper, newnode, freenode, freetree, debug, dumpnode.
  29.    I added cons just lately so you may see cases where I should have used
  30.    cons but didn't.
  31.  
  32.    Change log:
  33.    12/94 JDH first version       henckel@vnet.ibm.com
  34.    1/95  JDH second version
  35.    2/95  JDH vers 2.2 make xlatable, visible comments, tidy up menu
  36.    8/95  JDH vers 3.0 complete and uploaded to simtel
  37.    2/96  JDH vers 3.2 add palette management, Dutch, other fixes
  38.    4/96  JDH vers 3.3 French, focal length control, fill modes
  39.    6/96  JDH vers 3.4 autokey, autopick, 3D cylindrical mode, brightness
  40.                    fix exponential in calcnode, set k=1 (no calc) in poly3,
  41.                    add combine to expjoin, make factpoly smarter.
  42. */
  43. #define MAIN
  44. #include "alged.h"
  45.  
  46. long heapused();
  47.  
  48. /*--------------------------------------------------------------------
  49.    autosrc
  50.  
  51.    This little helper function will set/reset the default source
  52.    and target.  If src is and equation, it reassigns it to one
  53.    side or the other.  If tgt is NULL, it assigns it to a var.
  54.    The default is 'x' if it exists, else it is the first var found
  55.    in src.
  56. */
  57. node *findvar(node *s, char *name) {
  58.   int i; node *t;
  59.   if (s->kind==VAR && (!name || !strcmp(name,s->name)))
  60.     return s;
  61.   for (i=0; i<s->nump; ++i)
  62.     if (!!(t=findvar(s->parm[i],name))) return t;
  63.   return NULL;
  64. }
  65. void autosrc(int unset) {
  66.   static node* oldsrc;
  67.   static int fixtgt;
  68.   node *tmp;
  69.  
  70.   if (unset!=1) {        // SET
  71.     oldsrc = NULL;
  72.     if (src->kind==EQU)  {
  73.       oldsrc = src;
  74.       if (unset==2 && src->lf->kind==DIV)   // this is a hack for polydiv
  75.         src = src->lf;
  76.       else if (unset==2 && src->rt->kind==DIV)
  77.         src = src->rt;
  78.       else if (src->rt->kind < src->lf->kind && src->rt->kind != FUN)
  79.         src = src->rt;
  80.       else
  81.         src = src->lf;
  82.     }
  83.     fixtgt = !tgt;
  84.     if (tgt && tgt->kind==VAR && !findvar(src,tgt->name)) {
  85.       freetree(tgt);
  86.       tgt = NULL;
  87.     }
  88.     if (!tgt) {
  89.       tmp = findvar(src,"x");
  90.       if (tmp) tgt = newvar("x");
  91.       else {
  92.         tmp = findvar(src,NULL);
  93.         if (tmp) tgt = deepcopy(tmp);
  94.         else tgt = newvar("x");         // if all else fails, set tgt = x
  95.       }
  96.     }
  97.   }
  98.   else {           // RESET
  99.     if (oldsrc) src = oldsrc;
  100.     if (fixtgt && tgt) { freetree(tgt); tgt = NULL; }
  101.     oldsrc = NULL;
  102.     fixtgt = 0;
  103.   }
  104. }
  105.  
  106. /*--------------------------------------------------------------------
  107.    main
  108. */
  109. void main(int argc,char *argv[]) {
  110.   int i,x,y,b,done=0,mous=1;
  111.   node *tmp,*p;
  112.  
  113.   directvideo = 1;          /* don't use bios */
  114.   _wscroll = 0;            /* disable scrolling */
  115.  
  116.   gettextinfo(&ti);
  117.   heapsz = allocmem(32767,NULL);     /* find memory available */
  118.   heapsz *= 16;
  119.   if (heapsz<1) heapsz=400000L;   // default
  120.  
  121.   printf("ALGED: Algebra Editor, ver "__DATE__"\n\n");
  122.   printf("Copyright (c) 1994,1996 John Henckel\n");
  123.   printf("Permission to use, copy, modify, distribute and sell this software\n");
  124.   printf("and its documentation for any purpose is hereby granted without fee,\n");
  125.   printf("provided that the above copyright notice appear in all copies.\n");
  126.  
  127.   /*-----------------------------------------------------------------
  128.      initialize some critical messages to english
  129.   */
  130.   msg[1]="parser stack underflow.";
  131.   msg[2]="parser r-stack underflow.";
  132.   msg[3]="unable to open %s for infix read.";
  133.   msg[4]="Unexpected ) or ,";
  134.   msg[5]="unable to open %s for postfix read.";
  135.   msg[6]="missing function arity %s.";
  136.   msg[7]="too few args to %s.";
  137.   msg[8]="too many args to %s.";
  138.   msg[12]="mouse driver not found in memory.";
  139.   msg[13]="option not recognized %d.";
  140.   msg[16]="Unable to find menu file '%s'.";
  141.   /*-----------------------------------------------------------------
  142.      load data files
  143.   */
  144.   firf = NULL;
  145.   loadfile("alged.1st");
  146.   for (i=1; i<argc; ++i)
  147.     loadfile(argv[i]);
  148.   curf = firf;
  149.   if (loadmenu(argv[0])) return;
  150.   /*-----------------------------------------------------------------
  151.      init mouse
  152.   */
  153.   if (init_mouse() != -1) {
  154.     printf(msg[12]);
  155.     mous=0;
  156.   }
  157.   /*-----------------------------------------------------------------
  158.      main loop
  159.   */
  160.   src = curf;
  161.   show_menu();     // to establish mheight
  162.   while (!done) {
  163.     window(2,mheight+1,ti.screenwidth-1,ti.screenheight-1);
  164.     textattr(norm);
  165.     clrscr();
  166.     window(1,1,ti.screenwidth,ti.screenheight);   /* full */
  167.     display(curf);
  168.     show_menu();
  169.     _setcursortype(_NOCURSOR);
  170.     if (mous) show_mouse();
  171.     if (mous) while (!!(b = get_mouse(&x,&y)));
  172.     while (!mous || !(b = get_mouse(&x,&y)))
  173.       if (kbhit()) {
  174.         b = getch();
  175.         if (!b && kbhit()) b=300+getch();
  176.         break;
  177.       }
  178.     if (mous) hide_mouse();
  179.     _setcursortype(_NORMALCURSOR);
  180.     /*-----------------------------------------------------------------
  181.        check for keypresses
  182.     */
  183.     i=PP0;                    /* default = do nothing */
  184.     if (b==27) break;         /* escape */
  185.     if (b==332 && src) {          /* dump */
  186.       putch('\r'); putch('\n');
  187.       putch('\n'); putch('\n');
  188.       dumpnode(src,1);
  189.       do { getch(); } while (kbhit());
  190.       continue;
  191.     }
  192.     else if (b > 7) {
  193.       for (i=0; i<numm; ++i)
  194.         if (menu[i].hot==b) {
  195.           i=menu[i].fid;
  196.           break;
  197.         }
  198.       if (i==numm) continue;     /* invalid key */
  199.     }
  200.     else {                /* mouse click */
  201.       x=x/8+1; y=y/8+1;
  202.       i = selection(x,y);
  203.     }
  204.     if (i>=0) {
  205.       if (i==ESC) break;     /* escape */
  206.       switch (i) {
  207.       case HLP: showhelp(argv[0]); break;
  208.       case EQK:
  209.         if (src && tgt && src->kind!=EQU && tgt->kind!=EQU) {
  210.           tmp = newoper(EQU);
  211.           tmp->rt = tgt;
  212.           tmp->lf = deepcopy(src);
  213.           tgt = tmp;
  214.         }
  215.         break;
  216.       case DIS: if (src) while(distribute(src)); break;
  217.       case DI2: if (src) while(distribute_c(src)); break;
  218.       case CAL:
  219.         if (src) {
  220.           while(movenums(src,1,MUL));    /* move up for stretch rule */
  221.           while(calcnode(src,0));
  222.           while(movenums(src,0,MUL));
  223.           while(calcnode(src,0));       // alright, this is a hack for exp.
  224.         } break;
  225.       case COD:
  226.         if (src)
  227.           if (src->kind==DIV) while (distribute2(src));
  228.           else                while (comdeno(src));
  229.         break;
  230.       case SIM: if (src) simplify(src); break;
  231.       case SI2: if (src) simplify2(src,1); break;
  232.       case ASS: if (src) associate(src); break;
  233.       case PCO: if (src) { autosrc(0); polycoef(tgt,src);} break;
  234.       case RAT: if (src) ration(src); break;
  235.       case EXX: if (src) while (exexpand(src));  break;
  236.       case EXJ: if (src) {
  237.                   while (combine(src));
  238.                   while (expjoin(src)); } break;
  239.       case SBS: if (src && tgt && tgt->kind==EQU) substitution(src); break;
  240.       case QUA: if (src) { autosrc(0); quadratic(tgt,src); autosrc(1);} break;
  241.       case FAP: if (src) { autosrc(0); factrpoly(tgt,src); autosrc(1);} break;
  242.       case PRI: if (src) primefact(src); break;
  243.       case CUB: if (src) { autosrc(0); cubic(tgt,src); autosrc(1);} break;
  244.       case GRF: if (src) graph(tgt,src); break;
  245.       case XE0: if (src) cross_eq(src,0); break;
  246.       case XE1: if (src) cross_eq(src,1); break;
  247.       case P2T: src=curf; break;
  248.       case P2L: if (src && src->nump>0) src = src->lf; break;
  249.       case P2R: if (src && src->nump>1) src = src->rt; break;
  250.       case P2K:
  251.         if (src) {         /* copy pick to key */
  252.           p = deepcopy(src);
  253.           if (tgt) freetree(tgt);
  254.           tgt = p;
  255.         } break;
  256.       case PLY:
  257.         if (src) {
  258.           autosrc(2);
  259.           if (src->kind==DIV) {
  260.             tmp = polydiv(tgt,src->lf,src->rt);
  261.             if (tmp) movenode(src,tmp);
  262.             while (calcnode(src,1));     /* rmv 0+x and 0*x */
  263.           }
  264.           autosrc(1);
  265.         }
  266.         break;
  267.       case PPR: panx -= 10; break;
  268.       case PP0: panx = 0; break;
  269.       case PPL: panx += 10; break;
  270.       case CH8: ch8=1-ch8;
  271.         if (ch8) {
  272.           hline = 196;          vline = 179;
  273.           urc = 191;            llc = 192;
  274.           lrc = 217;            ulc = 218;
  275.           strcpy(piname,msg[33]);
  276.         }
  277.         else {
  278.           hline = '-';          vline = '|';
  279.           urc = '\\';           llc = '\\';
  280.           lrc = '/';            ulc = '/';
  281.           strcpy(piname,msg[32]);
  282.         }
  283.         clrscr();
  284.         break;
  285.       case WRI: writefile(keyin(msg[24])); break;   /* infix */
  286.       case LOD:
  287.            loadfile(keyin(msg[25]));
  288.            src = curf;
  289.            break;
  290.       case SAV: savefile(keyin(msg[26]));   break;   /* postfix only */
  291.       case CLR:
  292.         while (firf) {
  293.           tmp = firf;
  294.           firf = firf->next;
  295.           freetree(tmp);
  296.         } curf = src = NULL;
  297.         break;
  298.       case ADZ: insertkey(ADD); break;
  299.       case SUZ: insertkey(SUB); break;
  300.       case MUZ: insertkey(MUL); break;
  301.       case DIZ: insertkey(DIV); break;
  302.       case EXZ: insertkey(EXP); break;
  303.       case DEK: if (tgt) freetree(tgt); tgt=NULL; break;
  304.       case DEL:
  305.         tmp = curf;
  306.         if (!curf) break;
  307.         if (curf==firf) curf = firf = firf->next;
  308.         else curf = prevnode(curf)->next = curf->next;
  309.         freetree(tmp);
  310.         break;
  311.       case INK:
  312.         if (!tgt) break;
  313.         tgt->next = curf;
  314.         if (curf==firf) curf=firf=tgt;
  315.         else {
  316.           curf = prevnode(curf);
  317.           curf->next = tgt;
  318.           curf = tgt;
  319.         }
  320.         src = curf;
  321.         tgt = deepcopy(tgt);
  322.         break;
  323.       case ENT:
  324.         window(1,ti.screenheight-4,ti.screenwidth-1,ti.screenheight-1);
  325.         textattr(norm);
  326.         clrscr();
  327.         if (postfix) cputs(msg[30]); else cputs(msg[31]); putch('\r');
  328.         if (tgt) freetree(tgt);
  329.         if (postfix) tgt = load("con");
  330.         else tgt = loadinfix("con");
  331.         window(1,1,ti.screenwidth,ti.screenheight);
  332.         break;
  333.       case NXT:
  334.         if (curf) curf = curf->next;
  335.         if (!curf) curf = firf;
  336.         src = curf;
  337.         break;
  338.       case PRV:
  339.         if (curf==firf) curf = lastnode(curf);
  340.         else curf = prevnode(curf);
  341.         src = curf;
  342.         break;
  343.       default:
  344.         printf(msg[13],i); pause;
  345.       }
  346.     }
  347.     else {           /* not a menu selection */
  348.       tmp = curf;
  349.       p = NULL;
  350.       for (i=0; i<numsee && tmp; ++i) {
  351.         if (!!(p=find_node(tmp,x,y))) break;
  352.         tmp = tmp->next;
  353.       }
  354.       if (!p && tgt)
  355.         p = find_node(tgt,x,y);
  356.       if (b==1)                /* LMB */
  357.         src = p;
  358.       else if (p) {            /* RMB on an expression */
  359.         p = deepcopy(p);
  360.         if (tgt) freetree(tgt);
  361.         tgt = p;
  362.       }
  363.       else {                   /* RMB on nothing */
  364.         if (tgt) freetree(tgt);
  365.         tgt=NULL;
  366.       }
  367.     }
  368.   }
  369.   textattr(7);
  370.   clrscr();
  371. }
  372.  
  373.